# -*- coding: utf-8 -*-
"""
Macana XML-RPC Dispatcher for Taíno
Copyright (C) 2009, Joshua "jag" Ginsberg <jag@flowtheory.net

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import sys
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import AnonymousUser
from django.conf import settings
from django.core import exceptions
from macana.api import IMacanaAuthentication, IMacanaXMLRPCMethod
from macana import settings as app_settings
from taino.api import Component

class NoAuthentication(Component):
    implements = IMacanaAuthentication
    component_id = 'net.skwx.macana.NoAuthentication'
    component_description = 'No Authentication'
    
    def authenticate(self, request, method, method_args):
        request.user = AnonymousUser()
    
    def get_instructions(self):
        return u'No authentication system is configured at this site.'

class HttpBasicAuth(Component):
    implements = IMacanaAuthentication
    component_id = 'net.skwx.macana.HttpBasicAuth'
    component_description = 'HTTP Basic Authentication'
      
    def authenticate(self, request, method, method_args):
        if request.META.has_key('HTTP_AUTHORIZATION'):
            auth_method, auth_token = request.META['HTTP_AUTHORIZATION'].split(' ',1)
            username, password = auth_token.strip().decode('base64').split(':',1)
            user_obj = authenticate(username=username, password=password)
            if user_obj:
                request.user = user_obj
            else:
                request.user = AnonymousUser()
        else:
            request.user = AnonymousUser()
    
    def get_instructions(self):
        return (u'You may authenticate against the system by providing a '
                u'username and password in the form of HTTP basic '
                u'authorization as specified in the HTTP protocol RFC.\n')

class DjangoSessionLogin(Component):
    implements = [IMacanaAuthentication, IMacanaXMLRPCMethod]
    component_id = 'net.skwx.macana.DjangoSessionLogin'
    component_description = 'Django Session Login'
    
    def authenticate(self, request, method, method_args):
        if 'django.contrib.sessions.middleware.SessionMiddleware' not in \
                settings.MIDDLEWARE_CLASSES:
            raise exceptions.ImproperlyConfigured, u'To use the DjangoSessionLogin authentication plugin, you must have the SessionMiddleware installed.'
    
    def get_instructions(self):
        return (u'You may obtain a login session identifier by submitting a '
                u'username and password as arguments to the XML-RPC method '
                u'%s and submitting the response as a cookie named %s in '
                u'subsequent requests.') % (self.get_method_name(),
                                            settings.SESSION_COOKIE_NAME)
    
    def get_method_name(self):
        return u'system.login'
    
    def get_arg_list(self):
        return ['string', 'string']

    def get_return_type(self):
        return 'string'
    
    def authorize(self, request):
        return app_settings.AUTH_COMPONENT == self.component_id
    
    def handle_request(self, request, username, password):
        """Given a username and password value, returns a session identifier
        to be set as a cookie in subsequent requests as a login token. If
        the login fails, an empty string is returned."""
        user_obj = authenticate(username=username, password=password)
        if user_obj:
            login(request, user_obj)
            return request.session.session_key
        else:
            return ''

class DjangoSessionLogout(Component):
    implements = [IMacanaXMLRPCMethod,]
    component_id = 'net.skwx.macana.DjangoSessionLogout'
    component_description = 'Django Session Logout'
    
    def get_method_name(self):
        return u'system.logout'
    
    def get_arg_list(self):
        return ['string', 'string']

    def get_return_type(self):
        return 'boolean'
    
    def authorize(self, request):
        return True
    
    def handle_request(self, request):
        logout(request)
        return True
